package com.yuan.yblog.portal.service;


import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.CopyObjectRequest;
import com.aliyun.oss.model.CopyObjectResult;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.yuan.yblog.common.exception.Asserts;
import com.yuan.yblog.common.utils.StringUtils;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
@Service
@Slf4j
public class OssService {

    private String ENDPOINT;

    private String BUCKET_NAME;

    private OSSClient ossClient;

    private String urlPrefix;

    public OssService(@Value("${aliyun.oss.endpoint}") String ENDPOINT,
                      @Value("${aliyun.oss.bucketName}") String BUCKET_NAME,
                      @Autowired OSSClient ossClient) {
        this.ENDPOINT = ENDPOINT;
        this.BUCKET_NAME = BUCKET_NAME;
        this.ossClient = ossClient;
        this.urlPrefix = "https://" + this.BUCKET_NAME + "." + this.ENDPOINT + "/";
    }

    /**
     * 上传
     * @param file 文件
     * @param filePath 文件路径，不携带域名。案例：/user/avatar/1.jpg
     * @param objectMetadata 原数据配置，若不需要则只为null
     * @return 文件地址url
     */
    public String upload(@NotNull MultipartFile file, @NotNull String filePath, ObjectMetadata objectMetadata) {
        String returnUrl = "";
        try {
            //获取上传文件输入流
            InputStream inputStream = file.getInputStream();
            // 封装请求对象
            PutObjectRequest putObjectRequest = new PutObjectRequest(
                    BUCKET_NAME,
                    filePath,
                    inputStream,
                    objectMetadata
            );
            //操作上传
            ossClient.putObject(putObjectRequest);
            //把上传后把文件url返回
            returnUrl = urlPrefix + filePath;
        } catch (IOException e) {
            Asserts.fail("阿里云oss文件上传失败：" + e.getMessage());
        }
        return returnUrl;
    }

    /**
     * 删除文件
     * @param urls 文件地址
     */
    public int delete(List<String> urls) {
        int count = 0;
        if(urls == null || urls.isEmpty()) {
            return count;
        }
        for(String url : urls){
            if (StringUtils.isEmpty(url)) {
                continue;
            }
            String objectName = url;
            if (url.startsWith(urlPrefix)) {
                // 剔除前缀
                objectName = url.substring(urlPrefix.length());
            }
            try {
                ossClient.deleteObject(BUCKET_NAME, objectName);
                count++;
            } catch (OSSException e) {
                Asserts.fail("阿里云oss操作删除失败：" + e.getMessage());
            }
        }
        return count;
    }


    public boolean move(String originPath, String targetPath) {
        // 判断能否移动
        if (StringUtils.isEmpty(originPath)
                || !exist(originPath)
                || StringUtils.isEmpty(targetPath)
                || exist(targetPath)) {
            return false;
        }
        String origin = originPath;
        if (originPath.startsWith(urlPrefix)) {
            // 剔除前缀
            origin = originPath.substring(urlPrefix.length());
        }
        String target = targetPath;
        if (targetPath.startsWith(urlPrefix)) {
            // 剔除前缀
            target = targetPath.substring(urlPrefix.length());
        }
        // 判断是否为同一个路径
        if (origin.equals(target)) {
            return true;
        }
        // 操作移动
        try {
            CopyObjectRequest copyObjectRequest = new CopyObjectRequest(
                    BUCKET_NAME,
                    origin,
                    BUCKET_NAME,
                    target
            );
            //先copy到指定目录
            CopyObjectResult result = ossClient.copyObject(copyObjectRequest);
            //再删除源目录
            ossClient.deleteObject(BUCKET_NAME, origin);
        } catch (OSSException oe) {
            Asserts.fail("阿里云oss文件移动失败：" + oe.getMessage());
        }
        return true;
    }


    public boolean exist(String filePath) {
        String objectName = filePath;
        if (filePath.startsWith(urlPrefix)) {
            // 剔除前缀
            objectName = filePath.substring(urlPrefix.length());
        }
        return ossClient.doesObjectExist(BUCKET_NAME, objectName);
    }


    /**
     * getContentType
     * 解决问题，直接访问上传的图片地址，会让下载而不是直接访问
     * 设置设置 HTTP 头 里边的 Content-Type
     */
    public static String getContentType(String FilenameExtension) {
        System.out.println("FilenameExtension="+FilenameExtension);
        if (FilenameExtension.equalsIgnoreCase(".bmp")) {
            return "image/bmp";
        }
        if (FilenameExtension.equalsIgnoreCase(".gif")) {
            return "image/gif";
        }
        if (FilenameExtension.equalsIgnoreCase(".jpeg") ||
                FilenameExtension.equalsIgnoreCase(".jpg") ||
                FilenameExtension.equalsIgnoreCase(".png")) {
            return "image/jpg";
        }
        if (FilenameExtension.equalsIgnoreCase(".html")) {
            return "text/html";
        }

        if (FilenameExtension.equalsIgnoreCase(".txt")) {
            return "text/plain";
        }
        if (FilenameExtension.equalsIgnoreCase(".vsd")) {
            return "application/vnd.visio";
        }
        if (FilenameExtension.equalsIgnoreCase(".pptx") ||
                FilenameExtension.equalsIgnoreCase(".ppt")) {
            return "application/vnd.ms-powerpoint";
        }
        if (FilenameExtension.equalsIgnoreCase(".docx") ||
                FilenameExtension.equalsIgnoreCase(".doc")) {
            return "application/msword";
        }
        if (FilenameExtension.equalsIgnoreCase(".xml")) {
            return "text/xml";
        }
        return "image/jpg";
    }
}
